package com.hk.security.weixin.mp;

import com.hk.commons.util.AssertUtils;
import com.hk.commons.util.Constants;
import com.hk.core.authentication.api.UserPrincipal;
import com.hk.core.authentication.api.enums.ThirdAccountType;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

import java.util.Map;
import java.util.Objects;
import java.util.function.Function;


/**
 * 微信二维码认证提供者
 *
 * @author kevin
 * @date 2018年2月8日上午11:25:39
 */
@Slf4j
public record WeiXinMpAuthenticationProvider(
        Function<WxMpUser, UserPrincipal> function) implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        var wxMpUser = (WxMpUser) authentication.getPrincipal();
        var mpInfo = Map.of(ThirdAccountType.WX_ACCOUNT.name(), String.valueOf(true),
                Constants.OPEN_ID, wxMpUser.getOpenId(), Constants.UNION_ID, wxMpUser.getUnionId());
        UserPrincipal userPrincipal;
        if (Objects.isNull(function)) {
            log.warn("authenticationHandler is null");
            userPrincipal = new UserPrincipal(null, wxMpUser.getOpenId(), null);
        } else {
            userPrincipal = function.apply(wxMpUser);
            AssertUtils.notNull(userPrincipal, "principal Must not be null.");
        }
        userPrincipal.setAdditionalInfo(mpInfo);
        return new WeiXinMpAuthenticationToken(userPrincipal, null);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return WeiXinMpAuthenticationToken.class.isAssignableFrom(authentication);
    }

}
